package flow.action;

import com.alibaba.fastjson.JSONObject;
import flow.model.*;
import flow.service.FlowBusinessService;
import flow.service.FlowDefineService;
import flow.service.FlowInstanceService;
import flow.service.IFlowService;
import flow.util.FlowUtil;
import m.appserver.ActionRedirect;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.common.model.util.QueryOrder;
import m.common.service.Service;
import m.system.exception.MException;
import m.system.util.ClassUtil;
import m.system.util.GenerateID;
import m.system.util.JSONMessage;
import m.system.util.StringUtil;
import manage.action.ManageAction;
import manage.model.AdminLogin;

import java.util.ArrayList;
import java.util.List;

@ActionMeta(name="flow/flow")
public class FlowAction extends ManageAction {
	private FlowBusiness business;
	private FlowDefine define;
	private FlowInstance instance;
	private FlowInstanceSection instanceSection;
	private List<FlowSectionLink> sectionLinks;
	private FlowSectionLink selectLink;
	private String opinion;
	private List<AdminLogin> adminList= new ArrayList<>();
	private JSONObject flowModel;

	public JSONMessage doSave() throws Exception {
		AdminLogin admin=verifyAdminLogin();
		String msg=getService(FlowInstanceService.class).doSave(admin,instance, flowModel);
		return new JSONMessage(0).push("msg",msg);
	}
	public JSONMessage doProcess() throws Exception {
		AdminLogin admin=verifyAdminLogin();
		String msg=getService(FlowInstanceService.class).doProcess(admin,instance, selectLink, adminList,opinion,flowModel);
		return new JSONMessage(0).push("msg",msg);
	}
	@RequestMeta(params = {"edit"})
	public Object redirectPage(boolean edit) throws Exception {
		ActionRedirect ar=((IFlowService)getService((Class<Service>) ClassUtil.getClass(business.getBusiService())))
				.getRedirectPage(business,getSessionAdmin(),getSessionOrgGroup(),edit);
		return getResponse().redirect(ar);
	}
	public JSONMessage getFlowInfo() throws Exception {
		JSONMessage result=new JSONMessage(0);
		AdminLogin admin=verifyAdminLogin();
		if(null==business) throw new MException(this.getClass(), "参数错误");
		FlowBusiness fb=getService(FlowBusinessService.class).toFlowBusiness(business.getOid());
		if(null!=fb) business=fb;
		else{
			business=getService(FlowBusinessService.class)
				.toFlowBusiness(getSessionAdminOid(),getSessionOrgGroupOid(),GenerateID.generatePrimaryKey(),
						"","",business.getBusiService(),business.getBusiParam());
			getService(FlowInstanceService.class).doStart(business);
			business=getService(FlowBusinessService.class).toFlowBusiness(business.getOid());
		}
		if(StringUtil.isSpace(business.getBusiService())) throw new MException(this.getClass(), "business.busiService参数错误");
		instance=FlowUtil.getInstance4Business(business.getBusiService(), business);
		List<FlowInstanceSection> instanceSectionList;
		if(null!=instance) {
			//流程定义
			define=instance.getFlowDefine();
			//未完成的流程需返回当前环节和下一步选项
			if("N".equals(instance.getDoneStatus())) {
				instanceSection=getService(FlowInstanceService.class).getInstanceSection(instance.getOid(), instance.getCurrentSection().getOid(), admin.getOid(), null);
				sectionLinks=ModelQueryList.getModelList(
					FlowSectionLink.class, new String[] {"*","toSection.*"}, null,
					QueryCondition.and(
						QueryCondition.eq("fromSection.oid", instance.getCurrentSection().getOid()),
						QueryCondition.in("fromSection.oid",
							ModelQueryList.instance(FlowInstanceSection.class, new String[] {"flowSection.oid"}, null,
								QueryCondition.and(
									QueryCondition.eq("flowInstance.oid", instance.getOid()),
									QueryCondition.eq("user.oid", admin.getOid()),
									QueryCondition.eq("doneStatus", "N")
								)
							)
						)
					),
					QueryOrder.desc("isNext"),QueryOrder.asc("toSection.identity")
				);
				//判断并返回 可执行的下一环选项
				sectionLinks=FlowUtil.getService(business.getBusiService()).nextSectionLink(sectionLinks,instanceSection,business);
			}
			//所有环节执行记录
			instanceSectionList=ModelQueryList.getModelList(FlowInstanceSection.class, new String[] {"*","flowSection.*","user.*"}, null,
				QueryCondition.eq("flowInstance.oid", instance.getOid()),
				QueryOrder.asc("acceptDate")
			);
		}else {
			define=getService(FlowDefineService.class).getIssue(FlowUtil.getFlowId(business.getBusiService(),business.getBusiParam()));
			instance=new FlowInstance();
			instanceSectionList= new ArrayList<>();
			sectionLinks=new ArrayList<>();
		}
		if(null==define) throw new MException(this.getClass(), "没有找到发布的流程");
		result.push("business",business);
		result.push("instance",instance);
		result.push("define",define);
		result.push("instanceSection",instanceSection);
		result.push("sectionLinks",sectionLinks);
		result.push("instanceSectionList",instanceSectionList);
		return result;
	}


	public JSONObject getFlowModel() {
		return flowModel;
	}

	public void setFlowModel(JSONObject flowModel) {
		this.flowModel = flowModel;
	}

	public FlowBusiness getBusiness() {
		return business;
	}

	public void setBusiness(FlowBusiness business) {
		this.business = business;
	}

	public FlowDefine getDefine() {
		return define;
	}

	public void setDefine(FlowDefine define) {
		this.define = define;
	}

	public FlowInstance getInstance() {
		return instance;
	}

	public void setInstance(FlowInstance instance) {
		this.instance = instance;
	}

	public FlowInstanceSection getInstanceSection() {
		return instanceSection;
	}

	public void setInstanceSection(FlowInstanceSection instanceSection) {
		this.instanceSection = instanceSection;
	}

	public List<FlowSectionLink> getSectionLinks() {
		return sectionLinks;
	}

	public void setSectionLinks(List<FlowSectionLink> sectionLinks) {
		this.sectionLinks = sectionLinks;
	}

	public FlowSectionLink getSelectLink() {
		return selectLink;
	}

	public void setSelectLink(FlowSectionLink selectLink) {
		this.selectLink = selectLink;
	}

	public List<AdminLogin> getAdminList() {
		return adminList;
	}

	public void setAdminList(List<AdminLogin> adminList) {
		this.adminList = adminList;
	}
	public String getOpinion() {
		return opinion;
	}
	public void setOpinion(String opinion) {
		this.opinion = opinion;
	}

}
